home *** CD-ROM | disk | FTP | other *** search
/ Workbench Design / WB Collection.iso / workbench werkzeuge / palette tools / colorsaver / src / fileio.c < prev    next >
C/C++ Source or Header  |  1996-04-07  |  12KB  |  395 lines

  1. #include <exec/memory.h>
  2. #include <intuition/intuition.h>
  3. #include <intuition/gadgetclass.h>
  4. #include <libraries/asl.h>
  5. #include <libraries/gadtools.h>
  6. #include <dos/dos.h>
  7. #include <fcntl.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #include <clib/asl_protos.h>
  12. #include <clib/exec_protos.h>
  13. #include <clib/graphics_protos.h>
  14. #include <clib/gadtools_protos.h>
  15. #include <clib/dos_protos.h>
  16.  
  17. #include "protos.h"
  18. #include "gadgets.h"
  19. #include "defs.h"
  20.  
  21. extern UBYTE   ScanFileSpec[256];    /* filename for binary scan */
  22. extern struct  Screen    *Scr;            /* screen we open up on    */
  23. extern USHORT  *SavePal;            /* Snapshot of current palette*/
  24. extern UWORD   CycleSelect = 0;         /* ordinal value of cycle gad */
  25. extern UBYTE   LoadFile[32];        
  26. extern UBYTE   LoadDir[224];        
  27. extern UBYTE   ScanFile[32];        
  28. extern UBYTE   ScanDir[224];        
  29. extern UBYTE   FileSpec[224];
  30.  
  31. ULONG        *OffSetABase = NULL;    /* ptr to file offsets        */
  32. UBYTE           **OffSetSBase = NULL;     /* ptr to file offset strings   */
  33. SHORT              OffSetCount = 0;    /* number of offsets found  */
  34.  
  35.  
  36. /*-------------------------------------------------------------------------
  37.  * ASL requester tags & data.
  38.  *-------------------------------------------------------------------------*/
  39.  
  40. #define FILESAVE    0
  41. #define FILELOAD    1
  42. #define FILESCAN    2
  43.  
  44.  
  45.  
  46.  
  47. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  48.  * CAUTION! ASL_Window in the following structures is position sensitive 
  49.  * due to initialization in FileSelect().  It must be the first item      
  50.  * in the TagItem structure.                         
  51.  *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  52.  
  53. struct TagItem    SaveTags[] = {
  54.     ASL_Window,        NULL,              /* the window         */
  55.     ASL_Hail,        "Save File:",        /* Function text    */
  56.     ASL_File,        LoadFile,        /* file name buffer     */
  57.     ASL_Dir,        LoadDir,        /* path name buffer     */
  58.     ASL_OKText,        "Save",            /* "OK" Text        */
  59.     TAG_DONE    };
  60.  
  61. struct TagItem    LoadTags[] = {
  62.     ASL_Window,        NULL,              /* the window        */
  63.     ASL_Hail,        "Load File:",        /* Function text    */
  64.     ASL_File,        LoadFile,        /* file name buffer     */
  65.     ASL_Dir,        LoadDir,        /* path name buffer    */
  66.     ASL_OKText,        "Load",            /* "OK" Text        */
  67.     TAG_DONE     };
  68.  
  69. struct TagItem    ScanTags[] = {
  70.     ASL_Window,        NULL,              /* the window         */
  71.     ASL_Hail,        "Scan File:",        /* Function text    */
  72.     ASL_File,        ScanFile,        /* file name buffer     */
  73.     ASL_Dir,        ScanDir,        /* path name buffer     */
  74.     ASL_OKText,        "Scan",            /* "OK" Text        */
  75.     TAG_DONE    };
  76.  
  77. struct TagItem    *FileTags[] = {    SaveTags,
  78.                 LoadTags,
  79.                 ScanTags    };
  80.  
  81.  
  82.  
  83. /*=============================================================================
  84.  * Open an ASL file requester for either LOAD, SAVE or SCAN, depending on 
  85.  * "mode" argument
  86.  *===========================================================================*/
  87.  
  88. BOOL FileSelect( int mode, UBYTE *dir, UBYTE *file )
  89.  {
  90.     struct FileRequester    *freq;
  91.     struct TagItem *Tags;
  92.     BOOL fileselected;
  93.  
  94.     fileselected = FALSE;
  95.     Tags = FileTags[mode];
  96.  
  97.     /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  98.      * CAUTION! In order for the following statement to work, "ASL_Window"
  99.      * must be the first Item in the TagItem array
  100.      *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  101.  
  102.     Tags->ti_Data = (ULONG)ColorSaverWnd;
  103.  
  104.  
  105.     if ( freq = AllocAslRequest( ASL_FileRequest, Tags )) {
  106.         if ( RequestFile( freq )) {
  107.             strcpy( dir, freq->rf_Dir );
  108.             strcpy( FileSpec, freq->rf_Dir );
  109.             strcpy( file, freq->rf_File );
  110.         (void)AddPart(FileSpec,file,(ULONG)sizeof(FileSpec));
  111.         fileselected = TRUE;    
  112.         }
  113.  
  114.         FreeAslRequest( freq );
  115.     }
  116.  
  117.   return(fileselected);
  118.  
  119. }
  120.  
  121. /*=============================================================================
  122.  * Save a color palette
  123.  *===========================================================================*/
  124.  
  125. void SaveColors( UBYTE *file, ULONG colors )
  126. {
  127.  
  128.   int fh;
  129.   int w;
  130.   
  131.   if ((fh = open((char *)file, O_WRONLY|O_CREAT|O_TRUNC)) >= 0)
  132.    {
  133.     CopyMem((void *)Scr->ViewPort.ColorMap->ColorTable,(void *)SavePal,64L);
  134.     w = write(fh, (void *)SavePal, colors << 1);
  135.     close(fh);
  136.     if( w != colors << 1 )
  137.         (void)Notify(FILE_WRITE_IOERR, file);
  138.    }
  139.   else
  140.      (void)Notify(FILE_OPEN_FAIL, file);
  141. }
  142.  
  143.  
  144. /*=============================================================================
  145.  * Load a color palette
  146.  *===========================================================================*/
  147.  
  148. void LoadColors( UBYTE *file, ULONG colors )
  149. {
  150.  
  151.  int fh;
  152.  long filelen, bytesread, colorbytes;
  153.  USHORT *palette;
  154.  BOOL loadanyway = FALSE;
  155.  
  156.  colorbytes = colors << 1;
  157.  
  158.  if(!(palette = AllocMem(64L,MEMF_PUBLIC))) {
  159.      (void)Notify(LOAD_MALLOC_FAIL);
  160.      return;
  161.     }
  162.  
  163.  if ((fh = open(file,O_RDONLY)) >= 0) {    /* Try to open input file */
  164.      bytesread = read(fh, (char *)palette, colorbytes);
  165.      filelen = lseek(fh,0L,2);    /* Get the file length    */
  166.      close(fh);
  167.     }
  168.  
  169.  else {                   /* Couldn't open the file */
  170.      (void)Notify(FILE_OPEN_FAIL, file);
  171.      return;
  172.     }
  173.  
  174.  if (bytesread < 0) {              /* Uh-Oh! Read Error!     */
  175.      (void)Notify(FILE_READ_IOERR, file);
  176.      return;
  177.     }
  178. /* 
  179.  * If there are not enough or too many bytes in the file to match the 
  180.  * number of BitPlanes, alert the user
  181.  */   
  182.  
  183.  if ((colorbytes > bytesread)||(filelen > colorbytes)) 
  184.      loadanyway = Notify(PALETTE_SIZE_MISMATCH, colors, filelen >> 1);
  185.  
  186.  if(loadanyway || (bytesread == filelen) && (filelen == colorbytes))
  187.    {
  188.    LoadRGB4(&Scr->ViewPort,palette, filelen >> 1);
  189.  }
  190. }
  191.  
  192.  
  193. /*=============================================================================
  194.  * Search a binary file for its Color Table
  195.  *===========================================================================*/
  196. #define BUFSIZE 4096L        /* size of I/O buffer */
  197.  
  198. void *FindTable( UBYTE *file, USHORT *palette, ULONG colors )
  199. {
  200.  char *inbuffer;
  201.  long offset;            
  202.  char *buffptr;            /* memory pointer                      */
  203.  int bytesread=0;        /* bytes transferred during each read   */
  204.  long filepos=0;        /* total bytes to have been read in     */
  205.  int fh;
  206.  
  207.  OffSetCount = 0;
  208.  
  209.  if ((fh= open(file,O_RDONLY)) < 0) {    /* try to open input file */
  210.      (void)Notify(FILE_OPEN_FAIL, file);
  211.      return;
  212.     }
  213.  
  214.  if(!(inbuffer = AllocMem(BUFSIZE,MEMF_PUBLIC))) {
  215.      (void)Notify(BUFFER_MALLOC_FAIL);
  216.      return;
  217.     }
  218.  
  219.   /*
  220.    * read in the first block of chars 
  221.    */
  222.  
  223.   bytesread= read(fh,inbuffer,BUFSIZE);  
  224.   buffptr=inbuffer;
  225.  
  226.   for (;;)
  227.     {
  228.  
  229.      if(memcmp((void *)buffptr,(void *)palette,colors<<1)==0)
  230.       {                             /* did we get a match ??  */
  231.        filepos=lseek(fh,0L,1);
  232.        offset=((filepos-bytesread)+(buffptr-inbuffer)); 
  233.        if(AddOffSet(offset) < 0)
  234.         (void)Notify(OFFSET_MALLOC_FAIL);
  235.       }
  236.      buffptr++;
  237.  
  238.       /*
  239.        * this next bit of code counters the possibility of having the search
  240.        * palette chopped off at the end of the buffer, (would be my luck!)
  241.        * if less than sizeof(palette) bytes remain in the buffer, an lseek
  242.        * backwards is done and these are read back in to the beginning    
  243.        * of the next buffer full                                          
  244.        */
  245.  
  246.       if((BUFSIZE -(buffptr-inbuffer)) < colors<<1) 
  247.          {
  248.       filepos=lseek(fh,-colors<<1,1);
  249.           bytesread= read(fh,inbuffer,BUFSIZE); 
  250.       filepos=lseek(fh,0L,1);
  251.           buffptr=inbuffer;         /* reset pointers to start of buffer */
  252.          }
  253.       if(buffptr-inbuffer > bytesread)  /* got to the end of the file */ 
  254.          break;
  255.   }
  256.  
  257.   close(fh);
  258.  
  259.  
  260.   if(OffSetCount == 0)    /* Couldn't find a Color Table match    */
  261.    {
  262.     if(OffSetABase)
  263.        FreeOffSets();  
  264.  
  265.     (void)Notify(NO_COLORTABLE_FOUND);
  266.  
  267.     GT_SetGadgetAttrs(GAD(GD_CYCLE_GAD),ColorSaverWnd,NULL,GTCY_Labels,
  268.                        CYCLE_GAD0Labels,GA_Disabled, TRUE,TAG_END);
  269.     GT_SetGadgetAttrs(GAD(GD_WRITE_GAD),ColorSaverWnd,NULL,GA_Disabled,
  270.                        TRUE,TAG_END);
  271.    }
  272.   else
  273.    {
  274.      GT_SetGadgetAttrs(GAD(GD_CYCLE_GAD),ColorSaverWnd,NULL,GTCY_Labels,
  275.                        OffSetSBase,GA_Disabled, FALSE,TAG_END);
  276.      GT_SetGadgetAttrs(GAD(GD_WRITE_GAD),ColorSaverWnd,NULL,GA_Disabled,
  277.                        FALSE,TAG_END);
  278.      if(OffSetCount == 1)
  279.        (void)Notify(ONE_COLORTABLE_FOUND);
  280.      else
  281.        (void)Notify(MULT_COLORTABLE_FOUND,OffSetCount);
  282.  
  283.      strcpy(ScanFileSpec,file);  
  284.    }
  285.  
  286.   if(inbuffer) FreeMem(inbuffer,BUFSIZE);
  287.  
  288. }
  289.  
  290.  
  291. #define OFFSETBUFSZ 8    /* number of characters in cycle gadget        */
  292.  
  293. int AddOffSet(ULONG offset)
  294. {
  295.   ULONG *OffSetAPtr;     /* pointer to place to store actual offset         */
  296.   UBYTE *OffSetBuf;     /* pointer to place to store string version of above */
  297.   UBYTE **OffSetSPtr;   /* pointer to array of above strings             */
  298.  
  299.   OffSetCount++;
  300.   
  301. /*-------------------------------------------------------------------------
  302.  *  Store the offset in a continuously increasing array
  303.  *-------------------------------------------------------------------------*/
  304.  if(( OffSetABase = (ULONG *)realloc
  305.     (OffSetABase, OffSetCount * sizeof(ULONG))) == NULL)
  306.    return(-1);
  307.  
  308.   OffSetAPtr = OffSetABase + (OffSetCount -1);
  309.  *OffSetAPtr = offset;
  310.  
  311.  
  312. /*-------------------------------------------------------------------------
  313.  *  Allocate memory to hold the offset in string form 
  314.  *-------------------------------------------------------------------------*/
  315.   if(( OffSetBuf = (UBYTE *)malloc(OFFSETBUFSZ)) == NULL)
  316.     return(-1);
  317.  
  318. /*--------------------------------------------------------------------------
  319.  *  Store pointers to the above strings in a continuously increasing array
  320.  *-------------------------------------------------------------------------*/
  321.   if(( OffSetSBase=(UBYTE **)realloc
  322.      (OffSetSBase,((OffSetCount+1) * sizeof(UBYTE **)))) == NULL)
  323.     return(-1);
  324.  
  325.   OffSetSPtr = OffSetSBase + (OffSetCount -1);
  326.  *OffSetSPtr = OffSetBuf;
  327.  
  328. /*-------------------------------------------------------------------------
  329.  *  String pointer array needs to be NULL terminated for GadTools cycle
  330.  *  gadget
  331.  *-------------------------------------------------------------------------*/
  332.   *(++OffSetSPtr) = NULL;
  333.   sprintf(OffSetBuf,"%7d",offset);
  334.  
  335.   return(0);
  336.  
  337. }
  338.  
  339. void FreeOffSets( void )
  340. {
  341.  UBYTE **sptr;  
  342.  ULONG *optr; 
  343.  USHORT i;
  344.  
  345.  optr = OffSetABase;     /* Set pointers to head of actual offset array    */
  346.  sptr = OffSetSBase;     /* and also to array of pointers to strings    */
  347.  
  348.  for(i = 0; i < OffSetCount; i++, optr++, sptr++)
  349.  {
  350.   if(*sptr)free(*sptr); /* Free the string                */
  351.   if( sptr)free(sptr);  /* ...now free the pointer to the string    */
  352.   if( optr)free(optr);    /* ...and now the actual offset            */
  353.  }
  354.  
  355.  OffSetABase = NULL;    /* need to invalidate these pointers too...    */
  356.  OffSetSBase = NULL;
  357.  
  358. }
  359.  
  360. /*=============================================================================
  361.  * Write the new colors out to the file.
  362.  *===========================================================================*/
  363.  
  364. void Patch( UBYTE *file, USHORT *palette, ULONG colors )
  365. {
  366.  
  367.  int fh;
  368.  int w;
  369.  int doit;                  
  370.  ULONG offset;
  371.   
  372.  offset = (ULONG) *(OffSetABase + CycleSelect);
  373.  
  374.  doit = Notify(ABOUT_TO_WRITE, file, offset);
  375.  
  376.  if ( !doit )
  377.    return;
  378.  
  379.  if ( (fh = open(file,O_RDWR) ) < 0 ){    /* Try to open input file */
  380.      (void)Notify(FILE_OPEN_FAIL, file);
  381.      return;
  382.     }
  383.  else
  384.     {
  385.      lseek(fh,offset,0);      /* position to start of palette    */
  386.      w = write(fh, (void *)palette, colors << 1);
  387.      close(fh);
  388.      if( w != colors << 1 )
  389.         (void)Notify(FILE_WRITE_IOERR, file);
  390.      else
  391.         (void)Notify(WRITE_SUCCESS);
  392.     }
  393.  
  394. }
  395.